#!/usr/bin/env python
#coding=utf-8


import sys
import MySQLdb


'''
python操作MySQL数据库，模拟银行转账
'''


class Transfer_accounts(object):
    def __init__(self,conn):
        self.conn = conn


    #### 1、检查所输入的账号是否存在 ####

    def check_acct_available(self,source_acctid):
        cusor = self.conn.cursor()
        try:
            sql = "select * from tr_money where acctid=%s" %source_acctid
            cusor.execute(sql)
            print "check_acct_available:" + sql
            result = cusor.fetchall()
            if len(result)!=1:
                raise Exception("账号%s不存在" %source_acctid)
        finally:
            cusor.close()


    def has_enough_money(self,source_acctid,money):
        cursor = self.conn.cursor()
        try:
            sql = "select * from tr_money where acctid=%s and money>%s" % (source_acctid, money)
            cursor.execute(sql)
            print "has_enough_money:" + sql
            result = cursor.fetchall()
            if len(result) != 1:
                raise Exception("账号%s余额不足" % source_acctid)
        finally:
            cursor.close()

    #### 3、减款操作 ###
    def reduce_money(self, source_acctid, money):
        cursor = self.conn.cursor()
        try:
            # 数据库命令，减去对应减款人的金额数
            sql = "update tr_money set money=money-%s where acctid=%s" % (money, source_acctid)
            cursor.execute(sql)
            print "reduce_money:" + sql
            # 操作的execute()数据行数不等于1则减款失败
            if cursor.rowcount != 1:
                raise Exception("账号%s减款失败" % source_acctid)
        finally:
            cursor.close()

    #### 4、收款操作，与减款方法相同 ###
    def add_money(self, target_acctid, money):
        cursor = self.conn.cursor()
        try:
            sql = "update tr_money set money=money+%s where acctid =%s" % (money, target_acctid)
            cursor.execute(sql)
            print "add_money:" + sql
            if cursor.rowcount != 1:
                raise Exception("账号%s收款失败" % target_acctid)
        finally:
            cursor.close()

    #### 5、分别传入参数，代入上方函数，执行操作 ###
    def trans_for(self, source_acctid, target_acctid, money):
        try:
            self.check_acct_available(source_acctid)
            self.check_acct_available(target_acctid)
            self.has_enough_money(source_acctid, money)
            self.reduce_money(source_acctid, money)
            self.add_money(target_acctid, money)
            # 提交当前事务
            self.conn.commit()
        except Exception as e:
            # 若出错，回滚当前事务
            self.conn.rollback()
            raise e


if __name__ == "__main__":
    # source_acctid=sys.argv[1]
    # target_acctid=sys.argv[2]
    # money=sys.argv[3]
    # 建立与数据库的链接
    conn = MySQLdb.Connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        passwd='p@ssw0rd',
        db='atm',
        charset='utf8'
    )
    # 手动输入减款人、收款人、转款数
    source_acctid = raw_input("请输入减款人： ")
    target_acctid = raw_input("请输入收款人： ")
    money = raw_input("请输入转款数： ")
    # 将参数传入类中
    tr_money = Transfer_accounts(conn)
    try:
        tr_money.trans_for(source_acctid, target_acctid, money)
    except Exception as e:
        print"出现问题：" + str(e)
    finally:
        conn.close()
        # 关闭链接
